package cn.edu.zut.soft.graduate.topicCenter.bo.impl;

import cn.edu.zut.soft.basic.core.model.dao.Criteria;
import cn.edu.zut.soft.basic.core.model.dao.Example;
import cn.edu.zut.soft.graduate.base.bo.BasicBOImpl;
import cn.edu.zut.soft.graduate.base.dao.BasicDAO;
import cn.edu.zut.soft.graduate.core.constant.DeclareStatus;
import cn.edu.zut.soft.graduate.core.constant.InfoType;
import cn.edu.zut.soft.graduate.core.constant.IssueSource;
import cn.edu.zut.soft.graduate.core.constant.Role;
import cn.edu.zut.soft.graduate.core.constant.config.IKEY;
import cn.edu.zut.soft.graduate.core.design.BasicInfoStrategy;
import cn.edu.zut.soft.graduate.core.design.InfoStrategy;
import cn.edu.zut.soft.graduate.core.model.Impl.*;
import cn.edu.zut.soft.graduate.core.query.CompanyProjectRequestQuery;
import cn.edu.zut.soft.graduate.core.query.DeclareQuery;
import cn.edu.zut.soft.graduate.core.query.GroupQuery;
import cn.edu.zut.soft.graduate.core.query.InfoQuery;
import cn.edu.zut.soft.graduate.core.vo.LoginVO;
import cn.edu.zut.soft.graduate.groupCenter.bo.GroupBO;
import cn.edu.zut.soft.graduate.topicCenter.bo.CompanyProjectRequestBO;
import cn.edu.zut.soft.graduate.topicCenter.bo.DeclareBO;
import cn.edu.zut.soft.graduate.topicCenter.dao.CompanyProjectRequestDAO;
import cn.edu.zut.soft.graduate.topicCenter.pojo.ReplyCompanyProject;
import cn.edu.zut.soft.graduate.userCenter.bo.IdentityBO;
import cn.edu.zut.soft.graduate.userCenter.bo.InfoBO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.*;

/**
 * @author cc
 * @Date 2016/12/1
 * @value 1.0
 */
@Component
public class CompanyProjectRequestBOImpl extends BasicBOImpl<CompanyProjectRequest,CompanyProjectRequestQuery> implements CompanyProjectRequestBO {

    @Autowired
    private CompanyProjectRequestDAO<CompanyProjectRequest> companyProjectRequestDAO;

    @Autowired
    private DeclareBO declareBO;

    @Autowired
    private GroupBO groupBO;

    @Autowired
    private IdentityBO identityBO;

    @Autowired
    private InfoBO infoBO;

    @Override
    protected BasicDAO<Integer, CompanyProjectRequest> getDAO() {
        return companyProjectRequestDAO;
    }

    @Override
    protected List<Criteria> Query(CompanyProjectRequestQuery crq) {
        Criteria criteria = new Criteria();
        if (crq.getGroupId() != null){
            criteria.andEqualTo("group_id",crq.getGroupId());
        }
        if (crq.getPhone() != null){
            criteria.andEqualTo("phone",crq.getPhone());
        }
        if (crq.getIdentityId() != null){
            criteria.andEqualTo("identity_id",crq.getIdentityId());
        }
        if (StringUtils.isNotBlank(crq.getIdentityName())){
            criteria.andLike("identity_name",crq.getIdentityName()+"%");
        }
        if (crq.getStatus() != null){
            criteria.andEqualTo("`status`",crq.getStatus());
        }
        if (CollectionUtils.isNotEmpty(crq.getStatusList())){
            criteria.andIn("`status`",crq.getStatusList());
        }
        if (crq.getDel() != null){
            criteria.andEqualTo("del",crq.getDel());
        }else {
            criteria.andEqualTo("del",IKEY.ZERO);
        }
        return Collections.singletonList(criteria);
    }

    @Override
    public CompanyProjectRequest sendRequest(LoginVO loginVO, String content) {
        Assert.isTrue(StringUtils.isNotBlank(content),"申请理由不能为空");
        Assert.notNull(loginVO);
        List<Info> infoList = infoBO.queryByUser(loginVO.getId());
        Assert.notEmpty(infoList,"用户不具备权限");
        Map<String, String> map = getInfoMap(infoList);
        Assert.isTrue(StringUtils.isNotBlank(map.get(IKEY.GROUP_LEADER)),"非组长不可以申请");
        Assert.isTrue(StringUtils.isNotBlank(map.get(IKEY.GROUP_GROUP)),"无小组数据,请联系管理员");

        //小组不允许存在校内课题记录情况
        DeclareQuery declareQuery = new DeclareQuery();
        declareQuery.setGroupId(Integer.parseInt(map.get(IKEY.GROUP_LEADER)));
        declareQuery.setDeclareStatusList(Arrays.asList(DeclareStatus.values()));
        Assert.isTrue(CollectionUtils.isEmpty(declareBO.findByQuery(declareQuery).getData()),"小组存在校内申请记录,请解散小组,重新组队,直接申请。");

        CompanyProjectRequest cr = new CompanyProjectRequest();
        cr.setContent(content);
        cr.setGroupId(Integer.parseInt(map.get(IKEY.GROUP_GROUP)));
        cr.setPhone(loginVO.getPhone());
        cr.setStatus(DeclareStatus.ING);
        cr.setIdentityId(loginVO.getId());
        cr.setIdentityName(loginVO.getName());
        this.afterSave(cr,loginVO.getName());
        getDAO().insert(cr);
        return cr;
    }

    @Override
    public boolean isSendCompany(Integer groupId) {
        CompanyProjectRequestQuery companyProjectRequestQuery = new CompanyProjectRequestQuery();
        companyProjectRequestQuery.setGroupId(groupId);
        companyProjectRequestQuery.setStatusList(Arrays.asList(DeclareStatus.ING,DeclareStatus.YES));
        return CollectionUtils.isNotEmpty(findByQuery(companyProjectRequestQuery).getData());
    }

    @Override
    public CompanyProjectRequest successRequest(LoginVO loginVO, ReplyCompanyProject replyCompanyProject) {
        /**
         * 效验是否是同意操作
         * 效验小组是否存在,
         * 效验教师是否存在
         * 更改小组状态,
         * 更改小组学生状态
         */
        Assert.notNull(loginVO);
        Assert.notNull(replyCompanyProject);
        Assert.isTrue(replyCompanyProject.getDeclareStatus() == DeclareStatus.YES,"不存在的操作"+replyCompanyProject.getDeclareStatus());
        CompanyProjectRequest cr = getDAO().selectByPrimaryKey(replyCompanyProject.getRequestId());
        Assert.notNull(cr,"记录不存在");
        Assert.isTrue(cr.getStatus() == DeclareStatus.ING,"申请状态不符合要求:"+cr.getStatus());
        Group group = groupBO.get(cr.getGroupId());
        Assert.notNull(group,"小组不存在");
        Assert.isTrue(group.getStatus() == IssueSource.school,"小组状态错误"+group.getStatus());
        Assert.isTrue(group.getDel() == IKEY.ZERO,"小组已经删除");
        //放入小组人数
        cr.setGroupNum(group.getCount());
        //效验教师
        Identity teacher = identityBO.get(replyCompanyProject.getTeacherId());
        Assert.notNull(teacher,"用户不存在");
        Assert.isTrue(teacher.getRole() == Role.tea,"用户角色错误");
        Assert.isTrue(teacher.getDel() == IKEY.ZERO,"用户已经被删除");
        List<Info> infoList = infoBO.queryByInfoStrategy(Collections.<InfoStrategy>singletonList(new BasicInfoStrategy(InfoType.Group,IKEY.GROUP,group.getId().toString())));
        //关联信息
        for (Info info : infoList) {
            //放入指导教师
            infoBO.save(new BasicInfoStrategy(InfoType.Tea, IKEY.Guide, teacher.getId().toString()),info.getIdentityId(),loginVO.getName());
            infoBO.save(new BasicInfoStrategy(InfoType.Tea, IKEY.GuideName, teacher.getName()),info.getIdentityId(),loginVO.getName());
            //放入自主申请积极标记
            infoBO.save(new BasicInfoStrategy(InfoType.Positive,IKEY.Petitioner,teacher.getId().toString()),info.getIdentityId(),loginVO.getName());
        }
        //修改小组性质
        group.setStatus(IssueSource.myself);
        groupBO.update(group,loginVO.getName());
        //更新邀请状态
        cr.setStatus(DeclareStatus.YES);
        this.afterUpdate(cr,loginVO.getName());
        getDAO().updateByPrimaryKeySelective(cr);
        return cr;
    }

    @Override
    public CompanyProjectRequest isQualified(LoginVO loginVO) {
        Example example = new Example();
        example.createCriteria().andEqualTo("identity_id",loginVO.getId()).andIn("`status`", Arrays.asList(DeclareStatus.ING,DeclareStatus.YES)).andEqualTo("del",0);
        List<CompanyProjectRequest> crList = getDAO().selectByExample(example);
        if (CollectionUtils.isEmpty(crList)){
            return null;//代表具有权限
        }
        Assert.isTrue(crList.size() == 1,"系统数据错误,请联系管理员");
        return crList.get(0);
    }

    @Override
    public List<CompanyProjectRequest> groupRequest(Integer groupId) {
        CompanyProjectRequestQuery crq = new CompanyProjectRequestQuery();
        crq.setGroupId(groupId);
        crq.setStatusList(Arrays.asList(DeclareStatus.values()));
        return findByQuery(crq).getData();
    }

    @Override
    public List<CompanyProjectRequest> syncGroupNum(CompanyProjectRequestQuery crq) {
        List<CompanyProjectRequest> crList =  findByQuery(crq).getData();
        Group group;
        CompanyProjectRequest crs;
        for (CompanyProjectRequest cr : crList){
            group = groupBO.get(cr.getGroupId());
            crs = new CompanyProjectRequest();
            crs.setId(cr.getId());
            crs.setGroupNum(group.getCount());
            getDAO().updateByPrimaryKeySelective(crs);
        }
        return crList;
    }

    @Override
    public boolean isCreateCompanyIssue(Integer id, Integer groupId) {
        if (id == null || groupId == null){
            return false;
        }
        //小组方向为公司
        DeclareQuery declareQuery = new DeclareQuery();
        declareQuery.setGroupId(groupId);
        declareQuery.setDel(0);
        List<Declare> groupResult = declareBO.findByQuery(declareQuery).getData();
        if (CollectionUtils.isEmpty(groupResult)){
//            //没有题目
//            InfoQuery infoQuery = new InfoQuery();
//            infoQuery.setInfoType(InfoType.TOPIC);
//            infoQuery.setKey(IKEY.TopicId);
//            infoQuery.setIdentityId(id);
//            infoQuery.setDel(0);
//            List<Info>  infoList = infoBO.findByQuery(infoQuery).getData();
//            if (CollectionUtils.isEmpty(infoList)){
                //指导教师不为空
                InfoQuery infoQuery1 = new InfoQuery();
                infoQuery1.setInfoType(InfoType.Tea);
                infoQuery1.setKey(IKEY.Guide);
                infoQuery1.setDel(0);
                List<Info> infoList1 = infoBO.findByQuery(infoQuery1).getData();
                if (CollectionUtils.isNotEmpty(infoList1)){
                    //组长身份
                    InfoQuery infoQuery2 = new InfoQuery();
                    infoQuery2.setInfoType(InfoType.Group);
                    infoQuery2.setKey(IKEY.GroupLeader);
                    infoQuery2.setDel(0);
                    List<Info> infoList2 = infoBO.findByQuery(infoQuery2).getData();
                    if (CollectionUtils.isNotEmpty(infoList2)){
                        return true;
                    }
                }
//            }
        }
        return false;
    }

    private Map<String, String> getInfoMap(List<Info> list) {
        Map<String,String> map = new HashMap<>(list.size());
        for (Info info: list){
            map.put(info.getType()+info.getKey(),info.getValue());
        }
        return map;
    }
}
